package org.taobao.ibatiside.ui.util;

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.search.IJavaSearchConstants;
import org.eclipse.jdt.core.search.IJavaSearchScope;
import org.eclipse.jdt.core.search.SearchEngine;
import org.eclipse.jdt.internal.ui.dialogs.OpenTypeSelectionDialog;
import org.eclipse.jdt.ui.JavaElementLabelProvider;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerFilter;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.dialogs.ElementListSelectionDialog;
import org.eclipse.ui.internal.ide.dialogs.OpenResourceDialog;


public final class WorkspaceUtil {
	public static final IPackageFragment EMPTY_PKGFRG[] = new IPackageFragment[0];
	public static IPath getPackageFragementPath(IPath path){
		IResource resource = ResourcesPlugin.getWorkspace().getRoot().findMember(path);
		if (resource == null) return null;
		IJavaProject project = JavaCore.create(resource.getProject());
		if (project == null) return null;
		List<IPackageFragmentRoot> src_roots = getSourceRoot(project);
		for (IPackageFragmentRoot root : src_roots){
			 IPath root_path = root.getResource().getFullPath();
			 if(root_path.isPrefixOf(path)){
				 IPath pkg_path = path.removeFirstSegments(root_path.segmentCount());
				 return pkg_path;
			 }
		}
		return null;
	}
	public static String getClassPathString(IProject project, IPath fullPath){
		if (fullPath == null || fullPath.isEmpty()) return "";
		IProject in_project = project;
		IPath myPath =fullPath;
		if (in_project == null){
			//guess project
			IResource resource = null;
			IPath parentPath = myPath;
			while (resource == null){
				resource = ResourcesPlugin.getWorkspace().getRoot().findMember(parentPath);
				parentPath = parentPath.removeLastSegments(1);
				if (parentPath.isEmpty()) break;
			}
			if (resource == null) return null;
			else in_project =  resource.getProject();
		}
		IJavaProject jproject = JavaCore.create(in_project);
		List<IPackageFragmentRoot> src_roots = getSourceRoot(jproject);
		for (IPackageFragmentRoot root : src_roots){
			 IPath root_path = root.getResource().getFullPath();
			 if(root_path.isPrefixOf(fullPath)){
				 IPath pkg_path = fullPath.removeFirstSegments(root_path.segmentCount());
				 return pkg_path.removeFileExtension().toString().replace('/', '.');
			 }
		}
		return "??";
	}
	public static IJavaElement[] getSourcePackages(IJavaProject project) throws JavaModelException {
		IPackageFragmentRoot[] roots = project.getPackageFragmentRoots();
		IPackageFragment[] old_packs = new IPackageFragment[0];
		for (IPackageFragmentRoot r : roots){
			if (r.getKind() == IPackageFragmentRoot.K_SOURCE){
				IJavaElement[] children = r.getChildren();
				int org_len = old_packs.length;
				IPackageFragment[] new_packs = new IPackageFragment[org_len+children.length];
				System.arraycopy(old_packs, 0, new_packs, 0, org_len);
				System.arraycopy(children, 0, new_packs, org_len, children.length);
				old_packs = new_packs;
			}
		}
		return old_packs;
	}
	public static IPackageFragment choosePackage2(Shell shell, IPackageFragmentRoot root) throws JavaModelException {
		IJavaElement[] packs = root == null? EMPTY_PKGFRG : root.getChildren();
		ElementListSelectionDialog dialog= new ElementListSelectionDialog(shell, new JavaElementLabelProvider(JavaElementLabelProvider.SHOW_DEFAULT));
		dialog.setTitle("Choose a package");
		dialog.setMessage("package for new creating Data Object");
		dialog.setEmptyListMessage("No package, please create one");
		dialog.setMultipleSelection(false);
		dialog.setElements(packs);
		dialog.setIgnoreCase(false);
		if (dialog.open() == ElementListSelectionDialog.OK)
		{
			return (IPackageFragment) dialog.getFirstResult();
		}
		return null;
	}
	
	public static List<IPackageFragmentRoot> getSourceRoot(IJavaProject p){
		List<IPackageFragmentRoot> roots = new ArrayList<IPackageFragmentRoot>(4);
		try {
			IPackageFragmentRoot[] all = p.getPackageFragmentRoots();
			for (int i = 0; i < all.length; i++) {
				if (all[i].getKind() == IPackageFragmentRoot.K_SOURCE){
					roots.add(all[i]);
				}
			}
		} catch (JavaModelException e) {
			e.printStackTrace();
		}
		return roots;
	}
	public static IType openType2(Shell shell, IJavaProject project, boolean api){
		IJavaSearchScope scope = SearchEngine.createJavaSearchScope(new IJavaElement[]{project});
		OpenTypeSelectionDialog open_dialog = new OpenTypeSelectionDialog(shell,false,PlatformUI.getWorkbench().getProgressService(),scope, api ? IJavaSearchConstants.INTERFACE : IJavaSearchConstants.CLASS);
		open_dialog.create();
		if (open_dialog.open() == OpenTypeSelectionDialog.OK){
			return (IType) open_dialog.getFirstResult();
		}
		return null;
	}
	public static ViewerFilter FILE_IN_JAVA_PROJECT = new ViewerFilter() {
		@Override
		public boolean select(Viewer viewer, Object parentElement, Object element) {
			if (element instanceof IResource)
			{
				try {
					return ((IResource)element).getProject().hasNature(JavaCore.NATURE_ID);
				} catch (CoreException e) {
					e.printStackTrace();
					return false;
				}
			}
			return true;
		}
	};
	public static IFile chooseFile(final IContainer container, Shell shell){
		OpenResourceDialog res_dialog = new OpenResourceDialog(shell, container == null ? ResourcesPlugin.getWorkspace().getRoot() : container, IResource.FILE){
			@Override
			protected ItemsFilter createFilter() {
				if (container == null) addListFilter(FILE_IN_JAVA_PROJECT);
				return super.createFilter();
			}
		};
		if (res_dialog.open() == OpenResourceDialog.OK){
			Object first = res_dialog.getFirstResult();
			if (first != null && first instanceof IFile){
				return (IFile) first;			
			}
		}
		return null;
	}
	public static IFile findFile(IJavaProject project, String classPath){
		if (StringUtils.isBlank(classPath)) return null;
		List<IPackageFragmentRoot> roots = getSourceRoot(project);
		for (IPackageFragmentRoot iPackageFragmentRoot : roots) {
			IFolder folder = (IFolder) iPackageFragmentRoot.getResource();
			IResource file = folder.findMember(new Path(classPath));
			if (file != null && file instanceof IFile)
				return (IFile) file;
		}
		return null;
	}
}
